﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Newtonsoft.Json;
using YacGE.Script;

namespace YacGE.Map
{
    public class MapManager
    {
        private readonly GraphicsDeviceManager _graphicsDeviceManager;
        private readonly ScriptManager _scriptManager;

        private readonly List<MapObject> _mapObjectList;
        public KeyboardState CurrentKeyboardState { get; set; }
        public MouseState CurrentMouseState { get; set; }
        public Game Game { get; set; }

        private Vector2 _cameraPosition = Vector2.Zero;

        public MapManager(GraphicsDeviceManager graphicsDeviceManager, ScriptManager scriptManager, Game game)
        {
            _graphicsDeviceManager = graphicsDeviceManager;
            _scriptManager = scriptManager;
            _mapObjectList = new List<MapObject>();
            Game = game;
        }

        public void SetCameraPosition(Vector2 newPosition)
        {
            _cameraPosition = newPosition;
        }

        public void SetCameraPosition(int x, int y)
        {
            _cameraPosition = new Vector2(x, y);
        }

        public Vector2 GetCameraPosition()
        {
            return _cameraPosition;
        }

        public bool LoadMap(String mapName)
        {
            TextReader textReader = new StreamReader(@"Maps/" + mapName + "/" + mapName + ".yamap");

            var jsonMap = textReader.ReadToEnd();

            textReader.Close();

            var mapLoadingHelper = JsonConvert.DeserializeObject<MapLoadingHelper>(jsonMap);

            _mapObjectList.Clear();
            

            foreach (var pythonScriptFile in mapLoadingHelper.PythonScriptFiles)
                _scriptManager.LoadFromFile(@"Maps/" + mapName + "/scripts/" + pythonScriptFile, mapName);


            foreach (var mapObject in mapLoadingHelper.MapObjects)
            {
                mapObject.Initialize(_graphicsDeviceManager, _scriptManager, this, mapName);
                _mapObjectList.Add(mapObject);
            }

            return true;
        }

        public MapObject GetObject(String objectName)
        {
            return _mapObjectList.FirstOrDefault(mapObject => mapObject.ObjectName.Equals(objectName));
        }

        public List<MapObject> GetObjects()
        {
            return _mapObjectList;
        }

        public void AddObject(MapObject mapObject)
        {
            _mapObjectList.Add(mapObject);
        }

        public void UpdateObjects(GameTime gameTime, KeyboardState keyboardState, MouseState mouseState)
        {
            CurrentKeyboardState = keyboardState;
            CurrentMouseState = mouseState;

            foreach (var mapObject in _mapObjectList)
            {
                if (!mapObject.Update(gameTime))
                    break;
            }
            
        }

        public void DrawObjects(SpriteBatch spriteBatch)
        {
            foreach (var mapObject in _mapObjectList)
            {
                mapObject.Draw(spriteBatch);
            }
        }
    }
}